Skip to content

Strip basedirs from the compiler arguments too - #2840

Merged
sylvestre merged 1 commit into
mozilla:mainfrom
avikivity:basedirs-arguments
Sep 14, 2026
Merged

Strip basedirs from the compiler arguments too#2840
sylvestre merged 1 commit into
mozilla:mainfrom
avikivity:basedirs-arguments

Conversation

@avikivity

Copy link
Copy Markdown
Contributor

SCCACHE_BASEDIRS strips the base directories from the preprocessed source, but the compiler arguments are hashed verbatim. That leaves out the one thing that most reliably ties a cache entry to a single checkout: a flag that names the tree it is building.

-ffile-prefix-map=/home/user/project=.

The flag exists precisely so the object file does not depend on where the tree lives - every path it records is rewritten to . - so two checkouts of the same commit produce identical objects. They just never agree on the hash, because the flag itself spells the path out, and so they never share an entry. Which is the case basedirs is for.

Strip basedirs from each argument before hashing it, at the places where an argument is expected to spell a pathname, and only there: the whole argument, as in a source file or the path of a separated option; the value of an option written with an =, which covers either half of a prefix map; and the value glued to a short option such as -I. A basedir appearing anywhere else is left alone, so -DROOT="/home/user/project", which the compiler bakes into the output verbatim, still counts towards the hash.

Basedirs carry a trailing slash so that they only match whole path components; in an argument a component can also end at the = of a prefix map, or at the end of the argument, so accept those two as well. A sibling /home/user/project-docs is still not a match. The longest basedir wins.

Bump CACHE_VERSION and the preprocessor cache's FORMAT_VERSION, since the arguments now reach the hash as bytes rather than through OsString's Hash impl.

@codecov-commenter

codecov-commenter commented Sep 5, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.90210% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.30%. Comparing base (8c83b74) to head (c7c9894).

Files with missing lines Patch % Lines
src/util.rs 97.74% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2840      +/-   ##
==========================================
+ Coverage   76.22%   76.30%   +0.07%     
==========================================
  Files          72       72              
  Lines       39890    40027     +137     
==========================================
+ Hits        30407    30541     +134     
- Misses       9483     9486       +3     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@AJIOB

AJIOB commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Hi @avikivity ,

Thanks for your PR.

Please, fix the CI build

@avikivity

Copy link
Copy Markdown
Contributor Author

Update: apply cargo fmt

@avikivity

Copy link
Copy Markdown
Contributor Author

Update: increase test coverage

Comment thread src/util.rs
Cow::Owned(result)
}

/// Strip the base directories from a single compiler argument, for hashing.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we really need such a long comment?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is rather long, but I think the details are not obvious here.

It's easy to skip over an overlong comment, but not easy to reverse-engineer the details when the comment isn't there.

@sylvestre

Copy link
Copy Markdown
Collaborator

please add an integration test / end-to-end that should that it is fixed.
in tests/integration

@avikivity

Copy link
Copy Markdown
Contributor Author

please add an integration test / end-to-end that should that it is fixed. in tests/integration

Done.

@avikivity

Copy link
Copy Markdown
Contributor Author

Waiting for #2853

SCCACHE_BASEDIRS strips the base directories from the preprocessed
source, but the compiler arguments are hashed verbatim.  That leaves out
the one thing that most reliably ties a cache entry to a single checkout:
a flag that names the tree it is building.

  -ffile-prefix-map=/home/user/project=.

The flag exists precisely so the object file does not depend on where the
tree lives - every path it records is rewritten to `.` - so two checkouts
of the same commit produce identical objects.  They just never agree on
the hash, because the flag itself spells the path out, and so they never
share an entry.  Which is the case basedirs is for.

Strip basedirs from each argument before hashing it, at the places where
an argument is expected to spell a pathname, and only there: the whole
argument, as in a source file or the path of a separated option; the
value of an option written with an `=`, which covers either half of a
prefix map; and the value glued to a short option such as -I.  A basedir
appearing anywhere else is left alone, so -DROOT="/home/user/project",
which the compiler bakes into the output verbatim, still counts towards
the hash.

Basedirs carry a trailing slash so that they only match whole path
components; in an argument a component can also end at the `=` of a
prefix map, or at the end of the argument, so accept those two as well.
A sibling /home/user/project-docs is still not a match.  The longest
basedir wins.

Bump CACHE_VERSION and the preprocessor cache's FORMAT_VERSION, since the
arguments now reach the hash as bytes rather than through OsString's Hash
impl.

An integration test is added to tests/integration.
@avikivity

Copy link
Copy Markdown
Contributor Author

Update: added missing file-prefix-map integration test script

@sylvestre

Copy link
Copy Markdown
Collaborator

looks good, thanks for the test


  Testing file-prefix-map...
   Network sccache-integration-tests  Creating
   Network sccache-integration-tests  Created
   Container integration-test-file-prefix-map-1  Creating
   Container integration-test-file-prefix-map-1  Created
   Container integration-test-file-prefix-map-1  Starting
   Container integration-test-file-prefix-map-1  Started
  ===================================================================
  Testing: basedirs strip -ffile-prefix-map out of the hashed arguments
  ===================================================================
  
  ==========================================
  Test 1: without basedirs, the flag ties the entry to one checkout
  ==========================================
  [2026-09-14T09:11:28Z DEBUG sccache::config] Attempting to read config file at "/.config/sccache/config"
  sccache: Starting the server...
  [2026-09-14T09:11:28Z DEBUG sccache::config] Couldn't open config file: failed to open file `/.config/sccache/config`: No such file or directory (os error 2)
  [2026-09-14T09:11:28Z DEBUG sccache::config] Attempting to read config file at "/.config/sccache/config"
  [2026-09-14T09:11:28Z DEBUG sccache::config] Couldn't open config file: failed to open file `/.config/sccache/config`: No such file or directory (os error 2)
  sccache: Listening on address 127.0.0.1:4226
  [2026-09-14T09:11:29Z DEBUG sccache::config] Using basedirs for path normalization: ["/build/dir1/", "/build/dir2/"]
  [2026-09-14T09:11:29Z DEBUG sccache::commands] request_stats
  Cache hits: 1 (want 1), misses: 1 (want 1)
  ✓ PASS: basedirs strip -ffile-prefix-map from the hashed arguments
  
  ==========================================
  Test 3: a path the compiler bakes in verbatim still counts
  ==========================================
  [2026-09-14T09:11:30Z DEBUG sccache::config] Attempting to read config file at "/.config/sccache/config"
  [2026-09-14T09:11:30Z DEBUG sccache::config] Couldn't open config file: failed to open file `/.config/sccache/config`: No such file or directory (os error 2)
  [2026-09-14T09:11:30Z DEBUG sccache::config] Using basedirs for path normalization: ["/build/dir1/", "/build/dir2/"]
  sccache: Starting the server...
  [2026-09-14T09:11:30Z DEBUG sccache::config] Attempting to read config file at "/.config/sccache/config"
  [2026-09-14T09:11:30Z DEBUG sccache::config] Couldn't open config file: failed to open file `/.config/sccache/config`: No such file or directory (os error 2)
  [2026-09-14T09:11:30Z DEBUG sccache::config] Using basedirs for path normalization: ["/build/dir1/", "/build/dir2/"]
  sccache: Listening on address 127.0.0.1:4226
  [2026-09-14T09:11:30Z DEBUG sccache::config] Attempting to read config file at "/.config/sccache/config"
  [2026-09-14T09:11:30Z DEBUG sccache::config] Couldn't open config file: failed to open file `/.config/sccache/config`: No such file or directory (os error 2)
  [2026-09-14T09:11:30Z DEBUG sccache::config] Using basedirs for path normalization: ["/build/dir1/", "/build/dir2/"]
  [2026-09-14T09:11:30Z DEBUG sccache::commands] Server sent CompileStarted
  [2026-09-14T09:11:30Z DEBUG sccache::config] Attempting to read config file at "/.config/sccache/config"
  [2026-09-14T09:11:30Z DEBUG sccache::config] Couldn't open config file: failed to open file `/.config/sccache/config`: No such file or directory (os error 2)
  [2026-09-14T09:11:30Z DEBUG sccache::config] Using basedirs for path normalization: ["/build/dir1/", "/build/dir2/"]
  [2026-09-14T09:11:30Z DEBUG sccache::commands] request_stats
  [2026-09-14T09:11:30Z DEBUG sccache::config] Attempting to read config file at "/.config/sccache/config"
  [2026-09-14T09:11:30Z DEBUG sccache::config] Couldn't open config file: failed to open file `/.config/sccache/config`: No such file or directory (os error 2)
  [2026-09-14T09:11:30Z DEBUG sccache::config] Using basedirs for path normalization: ["/build/dir1/", "/build/dir2/"]
  [2026-09-14T09:11:30Z DEBUG sccache::commands] request_stats
  Cache hits: 0 (want 0), misses: 1 (want 1)
  [2026-09-14T09:11:30Z DEBUG sccache::config] Attempting to read config file at "/.config/sccache/config"
  [2026-09-14T09:11:30Z DEBUG sccache::config] Couldn't open config file: failed to open file `/.config/sccache/config`: No such file or directory (os error 2)
  [2026-09-14T09:11:30Z DEBUG sccache::config] Using basedirs for path normalization: ["/build/dir1/", "/build/dir2/"]
  [2026-09-14T09:11:30Z DEBUG sccache::commands] Server sent CompileStarted
  [2026-09-14T09:11:31Z DEBUG sccache::config] Attempting to read config file at "/.config/sccache/config"
  [2026-09-14T09:11:31Z DEBUG sccache::config] Couldn't open config file: failed to open file `/.config/sccache/config`: No such file or directory (os error 2)
  [2026-09-14T09:11:31Z DEBUG sccache::config] Using basedirs for path normalization: ["/build/dir1/", "/build/dir2/"]
  [2026-09-14T09:11:31Z DEBUG sccache::commands] request_stats
  [2026-09-14T09:11:31Z DEBUG sccache::config] Attempting to read config file at "/.config/sccache/config"
  [2026-09-14T09:11:31Z DEBUG sccache::config] Couldn't open config file: failed to open file `/.config/sccache/config`: No such file or directory (os error 2)
  [2026-09-14T09:11:31Z DEBUG sccache::config] Using basedirs for path normalization: ["/build/dir1/", "/build/dir2/"]
  [2026-09-14T09:11:31Z DEBUG sccache::commands] request_stats
  Cache hits: 0 (want 0), misses: 2 (want 2)
  ✓ PASS: a basedir outside a pathname position is left alone
  
  ==========================================
  All -ffile-prefix-map tests completed successfully!
  ==========================================
   Container integration-test-file-prefix-map-1  Stopping
   Container integration-test-file-prefix-map-1  Stopped
   Container integration-test-file-prefix-map-1  Removing
   Container integration-test-file-prefix-map-1  Removed
   Network sccache-integration-tests  Removing
   Network sccache-integration-tests  Removed
  file-prefix-map test completed
All backend tests completed

@sylvestre
sylvestre merged commit 4a78001 into mozilla:main Sep 14, 2026
51 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants